﻿using Simple.Tools.Entity;
using Simple.Tools.Extensions;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace Simple.Tools
/// <summary>
/// 版 本 钢易智企2.0 V 2.0.0 钢易智企2.0
/// Copyright (c) 2023 杭州钢易科技有限公司
/// 创建人：曾东明
/// 日 期：2024/3/19 14:05:37
/// 描 述：
/// </summary>
{
    internal class ByteCheckType : BaseCheckType
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="next"></param>
        public ByteCheckType(BaseCheckType next) : this()
        {
            this.next = next;
        }
        /// <summary>
        /// 
        /// </summary>
        public ByteCheckType() : base(typeof(byte))
        {
			nullableType = typeof(Nullable<Byte>);
		}
        /// <summary>
        /// /
        /// </summary>
        /// <param name="source"></param>
        /// <param name="member"></param>
        /// <returns></returns>
		public override bool IsNull(object source, PropertyInfo member)
        {

            if (PropertyEqualsType(member))
            {
                object obj = member.GetValue(source);
                if (SimpleCheck.IsNull(obj))
                {
                    return true;
                }
                return Verify(obj.ToByte());
            }
            if (next != null)
            {
                return next.IsNull(source, member);
            }
            return base.IsNull(source, member);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="member"></param>
        /// <returns></returns>
        public override bool IsNull(object source, FieldInfo member)
        {
            if (FieldEqualsType(member))
            {
                object obj = member.GetValue(source);
                if (SimpleCheck.IsNull(obj))
                {
                    return true;
                }
                return Verify(obj.ToByte());
            }

            return base.IsNull(source, member);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="b"></param>
        /// <returns></returns>
        public bool Verify(byte b)
        {
            return b == SimpleConstant.GetDefaultByte();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="map"></param>
        /// <param name="pSource"></param>
        /// <param name="pTarget"></param>
        /// <param name="sourceValue"></param>
        /// <param name="Target"></param>
        public override void SetValue(MapToAttribute map, PropertyInfo pSource, PropertyInfo pTarget, object sourceValue, object Target)
        {
            base.SetValue(map, pSource, pTarget, sourceValue, Target);
            if (EqualsType(map.TargetType))
            {
                byte lvalue = sourceValue.ToByte();
                pTarget.SetValue(Target, lvalue);
            }
            else
            {
                if (next != null)
                {
                    next.SetValue(map, pSource, pTarget, sourceValue, Target);
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="map"></param>
        /// <param name="pSource"></param>
        /// <param name="pTarget"></param>
        /// <param name="sourceValue"></param>
		public override  object GetTargetValue(MapToAttribute map, Type pSource, Type pTarget, object sourceValue)
		{
			base.SetValue(map, pSource, pTarget, sourceValue);
			if (EqualsType(map.TargetType))
			{
				return  sourceValue.ToByte();
			}
			else
			{
				if (next != null)
				{
					return next.GetTargetValue(map, pSource, pTarget, sourceValue);
				}
			}
            return null;
		}
        /// <summary>
        /// 
        /// </summary>
        /// <param name="map"></param>
        /// <param name="pSource"></param>
        /// <param name="pTarget"></param>
        /// <param name="sourceValue"></param>
        /// <param name="Target"></param>
		public override void SetValue(MapToAttribute map, FieldInfo pSource, FieldInfo pTarget, object sourceValue, object Target)
        {
            base.SetValue(map, pSource, pTarget, sourceValue, Target);
            if (EqualsType( map.TargetType))
            {
                byte lvalue = sourceValue.ToByte();
                pTarget.SetValue(Target, lvalue);
            }
            else
            {
                if (next != null)
                {
                    next.SetValue(map, pSource, pTarget, sourceValue, Target);
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="property"></param>
        /// <param name="value"></param>
        /// <param name="target"></param>
        public override void SetValue(PropertyInfo property, object value, object target)
        {
            if (PropertyEqualsType(property))
            {
                property.SetValue(value, value.ToByte());
            }
            else
            {
                if (next != null)
                {
                    next.SetValue(property, value, target);
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="fieldinfo"></param>
        /// <param name="value"></param>
        /// <param name="target"></param>
        public override void SetValue(FieldInfo fieldinfo, object value, object target)
        {
            if (FieldEqualsType(fieldinfo))
            {
                fieldinfo.SetValue(value, value.ToByte());
            }
            else
            {
                if (next != null)
                {
                    next.SetValue(fieldinfo, value, target);
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="value"></param>
        /// <param name="prop"></param>
        /// <param name="max"></param>
        /// <param name="min"></param>
        /// <returns></returns>
		public override KeyValue<bool, string> VerifyRange(object value, PropertyInfo prop,double max, double min)
		{
			KeyValue<bool, string> result = new KeyValue<bool, string>() { Key = true };

			if (PropertyEqualsType(prop))
			{
				double dValue = value.ToDouble();

				if (max > -1)
				{
					if (dValue > max)
					{
						result.Key = false;
						result.Value = $"不得大于最大值{max}!";
					}
				}

				if (min > -1)
				{
					if (dValue < min)
					{
						result.Key = false;
						result.Value = $"必须大于最小值{min}!";
					}
				}
			}
			else if (next != null)
			{
				return next.VerifyRange(value, prop, max, min);
			}
			else
			{
				return base.VerifyRange(value, prop, max, min);
			}

			return result;
		}
	}
}
